using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.Common;
using System.Threading;
using System.Windows.Forms;
using System.Resources;
using System.Reflection;
using System.Text.RegularExpressions;
using System.IO;

namespace SqlPrompt
{
	class App
	{
        public static Config Config { get; set; }
        static CommandProcessor commandProcessor = new CommandProcessor();
		
		[STAThread] static void Main(string[] args)
		{
			try
			{
				DisplayIntroText();
				LoadConfig();
                InitInputBuffer();
                InitOutputBuffer();
                
				while (true)
				{
                    NewLine();
					string cmd = Prompt("");
                    if (!string.IsNullOrEmpty(cmd))
                    {
                        NewLine();
                        if (!commandProcessor.ProcessCommand(cmd))
                            break;
                    }
				}
			}
			catch (Exception e)
			{
				Error("System Error: " + e.Message + Environment.NewLine + e.StackTrace);
			}
			finally
			{
                commandProcessor.Dispose();
			}
		}

		static void DisplayIntroText()
		{
            ConsoleUtil.WriteResourceToConsole("intro.txt");
		}

		static void LoadConfig()
		{
			try
			{
				Config = Config.Load();
			}
			catch (Exception e)
			{
				Error("An error occured when loading the config file. The program will run with a blank config. Error: " + e.Message);
			}

			if (Config == null)
				Config = new Config();
		}

        static void InitInputBuffer()
        {
            byte[] inputBuffer = new byte[1024];
            Stream inputStream = Console.OpenStandardInput(inputBuffer.Length);
            Console.SetIn(new StreamReader(inputStream));
        }

        static void InitOutputBuffer()
        {
            Console.SetBufferSize(3000, 500);
        }

		public static string Prompt(string msg)
		{
			return Prompt(msg, false);
		}

		public static string Prompt(string msg, string defaultValue)
		{
			string value = Prompt(msg, false);
			return !string.IsNullOrEmpty(value) ? value : defaultValue;
		}

		public static string Prompt(string msg, bool singleKey)
		{
			Console.ForegroundColor = ConsoleColor.Yellow;
			Console.Write(msg + "> ");

			Console.ForegroundColor = ConsoleColor.Cyan;

			if (singleKey)
			{
				string s = "" + Console.ReadKey(true).KeyChar;
				App.NewLine();
				return s;
			}
			else
				return Console.ReadLine();
		}

		public static bool YesNo(string msg)
		{
			string key = App.Prompt(msg + " Y/N", true);
			return key.ToLower() == "y";
		}

		public static void Msg(string msg)
		{
			Console.BackgroundColor = ConsoleColor.Black;
			Console.ForegroundColor = ConsoleColor.Green;
			Console.WriteLine(msg);
		}

		public static void ColumnHeading(string name, int padding, bool isFirst)
		{
			if (!isFirst)
			{
				Console.BackgroundColor = ConsoleColor.Black;
				Console.Write(" ");
			}

			Console.BackgroundColor = ConsoleColor.DarkGray;
			Console.ForegroundColor = ConsoleColor.White;
			Console.Write(name.PadRight(padding));

			Console.BackgroundColor = ConsoleColor.Black;
		}

		public static void Error(string msg)
		{
			// Make sure the string doesn't have a trailing line feed. This is just for neatness on-screen.
			msg = StringUtil.RemoveTrailingCrLf(msg);

			Console.BackgroundColor = ConsoleColor.Black;
			Console.ForegroundColor = ConsoleColor.Red;
			Console.WriteLine(msg);
		}

		public static void NewLine()
		{
			Console.Write(Environment.NewLine);
		}
	}
}
